package com.tang.crm.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tang.crm.entity.SaleChance;
import com.tang.crm.enums.DevResult;
import com.tang.crm.enums.StateStatus;
import com.tang.crm.mapper.SaleChanceMapper;
import com.tang.crm.dto.SaleChanceDto;
import com.tang.crm.service.SaleChanceService;
import com.tang.crm.utils.AssertUtil;
import com.tang.crm.utils.PhoneUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class SaleChanceServiceImpl extends ServiceImpl<SaleChanceMapper, SaleChance> implements SaleChanceService {

    @Autowired
    private SaleChanceMapper saleChanceMapper;

    /**
     * 测试自定义分页sql
     * @param saleChanceDto
     * @return
     */
    @Override
    public Map<String, Object> querySaleChanceByParams(SaleChanceDto saleChanceDto) {
        Map<String, Object> map = new HashMap<>();
        Page<SaleChance> pageInfo = new Page<>(saleChanceDto.getPage(), saleChanceDto.getLimit());
        IPage<Map<String, Object>> mapIPage = saleChanceMapper.selectByParams(pageInfo, saleChanceDto);
        map.put("code", 0);
        map.put("msg", "");
        map.put("count", mapIPage.getTotal());
        map.put("data", mapIPage.getRecords());
        return map;
    }

    /**
     * 添加营销机会
     *  1. 参数校验
     *      customerName客户名称    非空
     *      linkMan联系人           非空
     *      linkPhone联系号码       非空，手机号码格式正确
     *  2. 设置相关参数的默认值
     *      createMan创建人        当前登录用户名
     *      assignMan指派人
     *          如果未设置指派人（默认）
     *              state分配状态 （0=未分配，1=已分配）
     *                  0 = 未分配
     *              assignTime指派时间
     *                  设置为null
     *              devResult开发状态 （0=未开发，1=开发中，2=开发成功，3=开发失败）
     *                  0 = 未开发 （默认）
     *          如果设置了指派人
     *               state分配状态 （0=未分配，1=已分配）
     *                  1 = 已分配
     *               assignTime指派时间
     *                  系统当前时间
     *               devResult开发状态 （0=未开发，1=开发中，2=开发成功，3=开发失败）
     *                  1 = 开发中
     *      isValid是否有效  （0=无效，1=有效）
     *          设置为有效 1= 有效
     *      createDate创建时间
     *          默认是系统当前时间
     *      updateDate
     *          默认是系统当前时间
     *  3. 执行添加操作，判断受影响的行数
     * @param saleChance
     */
    @Override
    public void saveSaleChance(SaleChance saleChance) {
        // 参数校验
        checkSaleChanceParams(saleChance.getCustomerName(), saleChance.getLinkMan(), saleChance.getLinkPhone());
        // 设置有效
        saleChance.setIsValid(1);
        // 设置更新，创建时间
        saleChance.setCreateDate(new Date());
        saleChance.setUpdateDate(new Date());
        // 判断是否设置了指派人
        if (StringUtils.isBlank(saleChance.getAssignMan())){
            // 为空，则没有设置指派人
            // state = 0 未分配
            saleChance.setState(StateStatus.UNSTATE.getType());
            // 设置指派时间为空
            saleChance.setAssignTime(null);
            // devResult开发状态 （0=未开发，1=开发中，2=开发成功，3=开发失败）  0 = 未开发 （默认）
            saleChance.setDevResult(DevResult.UNDEV.getStatus());
        }else{
            // 设置了指派人
            // state = 1 未分配
            saleChance.setState(StateStatus.STATED.getType());
            // 设置指派时间
            saleChance.setAssignTime(new Date());
            // devResult开发状态 （0=未开发，1=开发中，2=开发成功，3=开发失败）  1 = 开发中
            saleChance.setDevResult(DevResult.DEVING.getStatus());
        }
        // 执行添加操作
        AssertUtil.isTrue(saleChanceMapper.insert(saleChance) < 1, "机会数据添加失败");
    }

    /**
     * 更新营销机会
     *  1. 参数校验
     *      营销机会ID  非空，数据库中对应的记录存在
     *      customerName客户名称    非空
     *      linkMan联系人           非空
     *      linkPhone联系号码       非空，手机号码格式正确
     *
     *  2. 设置相关参数的默认值
     *      updateDate更新时间  设置为系统当前时间
     *      assignMan指派人
     *          原始数据未设置
     *              修改后未设置
     *                  不需要操作
     *              修改后已设置
     *                  assignTime指派时间  设置为系统当前时间
     *                  分配状态    1=已分配
     *                  开发状态    1=开发中
     *          原始数据已设置
     *              修改后未设置
     *                  assignTime指派时间  设置为null
     *                  分配状态    0=未分配
     *                  开发状态    0=未开发
     *              修改后已设置
     *                  判断修改前后是否是同一个指派人
     *                      如果是，则不需要操作
     *                      如果不是，则需要更新 assignTime指派时间  设置为系统当前时间
     *
     *  3. 执行更新操作，判断受影响的行数
     * @param saleChance
     */
    @Override
    public void updateSaleChance(SaleChance saleChance) {
        /* 1. 参数校验  */
        //  营销机会ID  非空，数据库中对应的记录存在
        SaleChance saleChanceData = saleChanceMapper.selectById(saleChance.getId());
        AssertUtil.isTrue(saleChanceData == null, "更新记录不存在");
        // 参数校验
        checkSaleChanceParams(saleChance.getCustomerName(), saleChance.getLinkMan(), saleChance.getLinkPhone());
        /* 2. 设置相关参数的默认值 */
        // updateDate更新时间  设置为系统当前时间
        saleChance.setUpdateDate(new Date());
        // 判断原始数据中的 assignMan (指派人) 是否存在
        if (StringUtils.isBlank(saleChanceData.getAssignMan())){
            // 不存在
            if (!StringUtils.isBlank(saleChance.getAssignMan())){
                // 原始数据不存在，修改后存在 assignMan
                // 更新指派时间
                saleChance.setAssignTime(new Date());
                // 分配状态 1->以分配
                saleChance.setState(StateStatus.STATED.getType());
                // 开发状态 1->开发中
                saleChance.setDevResult(DevResult.DEVING.getStatus());
            }
        }else{
            // 存在
            if (StringUtils.isBlank(saleChance.getAssignMan())){
                // 原始数据存在，修改后没有设置 assignMan
                // 更新指派时间
                saleChance.setAssignTime(null);
                // 分配状态 0->以分配
                saleChance.setState(StateStatus.UNSTATE.getType());
                // 开发状态 0->未开发
                saleChance.setDevResult(DevResult.UNDEV.getStatus());
            }else{
                // 原始数据存在，修改后也设置了 assignMan
                if (!saleChance.getAssignMan().equals(saleChanceData.getAssignMan())){
                    // 原始数据和修改的 assignMan 不同
                    // 更新指派时间
                    saleChance.setAssignTime(new Date());
                }else{
                    // 原始数据和修改的 assignMan 相同
                    // 修改更新时间为以前的时间
                    saleChance.setAssignTime(saleChanceData.getAssignTime());
                }
            }
        }
        AssertUtil.isTrue(saleChanceMapper.updateById(saleChance) < 1, "更新数据失败");
    }

    /**
     * 删除营销机会信息
     * @param saleChanceIds
     */
    @Override
    public void deleteSaleChances(List<Integer> saleChanceIds) {
        // 判断传入的字符串是否存在和为空
        AssertUtil.isTrue(saleChanceIds == null || saleChanceIds.size() == 0, "请选择要删除的数据");
        // 判断删除是否成功执行
        AssertUtil.isTrue(saleChanceMapper.deleteBatchIds(saleChanceIds) != saleChanceIds.size(), "删除营销机会信息失败");
    }

    /**
     * 更新营销机会的开发状态
     * @param id
     * @param devResult
     */
    @Override
    public void updateSaleChanceDevResult(Integer id, Integer devResult) {
        // 判断id是否为空
        AssertUtil.isTrue(id == null, "待更新记录不存在");
        // 获取数据库中的营销机会
        SaleChance saleChance = saleChanceMapper.selectById(id);
        // 判断营销机会是否存在
        AssertUtil.isTrue(saleChance == null, "待更新记录不存在");
        // 更新开发状态
        saleChance.setDevResult(devResult);
        // 执行更新操作，判断受影响的函数
        AssertUtil.isTrue(saleChanceMapper.updateById(saleChance) != 1, "更新开发状态失败");
    }


    /**
     * 参数校验
     *   customerName客户名称    非空
     *   linkMan联系人           非空
     *   linkPhone联系号码       非空，手机号码格式正确
     * @param customerName
     * @param linkMan
     * @param linkPhone
     */
    public void checkSaleChanceParams(String customerName, String linkMan, String linkPhone){
        // 判断用户名不为空
        AssertUtil.isTrue(StringUtils.isBlank(customerName), "用户名不能为空");
        // 判断联系人不为空
        AssertUtil.isTrue(StringUtils.isBlank(linkMan), "联系人不能为空");
        // 判断电话不为空
        AssertUtil.isTrue(StringUtils.isBlank(linkPhone), "联系电话不能为空");
        // 判断电话格式是否合法
        AssertUtil.isTrue(!PhoneUtil.isMobile(linkPhone), "电话格式不合法");
    }
}
